//
//  MVVMNavigator.swift
//  test-ios
//
//  Created by wyz5204 on 2023/4/7.
//

import Foundation
import UIKit
import RxSwift
import RxCocoa
import SafariServices

final class MVVMNavigator{
    
    public static var shared = MVVMNavigator()
    
    
    private init() {
    }
    
    // MARK: - segues list, all app scenes
    enum Scene {
        case tabs(viewModel: MVVMBaseViewModel)
        case login
        case safari(URL)
        case safariController(URL)
        case webController(URL)
        case github
        case projectDetail(projectBean : ProjectBean)
        case openChatSession(session : ChatSession)
    }
    
    
    enum Transition {
        case root(in: UIWindow)
        case modal
        case detail
        case alert
        case mine
    }
    
    func navigator(_ scene : Scene) -> UIViewController{
        switch scene {
        case .tabs(let viewModel):
            break ;
        case .login:
            break ;
        case .safari(let url):
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            break ;
        case .safariController(let url):
            return SFSafariViewController(url: url)
        case .webController(let url):
            return MVVMWebViewController(viewModel: MVVMWebViewModel(url))
        case .github:
            return GithubLoginViewController(viewModel: GithubViewModel())
        case .projectDetail(let projectBean):
            return ProjectDetailViewController(viewModel: ProjectDetailViewModel(project: projectBean))
        case .openChatSession(let sessionBean):
            return ChatViewController(viewModel: ChatViewModel(sessionBean))
        }
        return AboutViewController(viewModel : AboutViewModel())
    }
    
    func pop(_ sender: UIViewController?, toRoot: Bool = false) {
        if toRoot {
            sender?.navigationController?.popToRootViewController(animated: true)
        } else {
            sender?.navigationController?.popViewController(animated: true)
        }
    }
    
    func dismiss(sender: UIViewController?) {
        sender?.navigationController?.dismiss(animated: true, completion: nil)
    }
    
    func show(segue: Scene, sender: UIViewController?, transition: Transition = .mine) {
        show(target: navigator(segue), sender: sender, transition: transition)
    }
    
    private func show(target: UIViewController, sender: UIViewController?, transition: Transition) {
        
        switch transition {
        case .root(in: let window):
            UIView.transition(with: window, duration: 0.5, options: .transitionFlipFromLeft, animations: {
                window.rootViewController = target
            }, completion: nil)
            return
        default: break
        }
        
        guard let sender = sender else {
            fatalError("You need to pass in a sender for .navigation or .modal transitions")
        }
        
        if let nav = sender as? UINavigationController {
            // push root controller on navigation stack
            nav.pushViewController(target, animated: false)
            return
        }
        
        switch transition {
        case .modal:
            // present modally
            DispatchQueue.main.async {
                let nav = UINavigationController(rootViewController: target)
                sender.present(nav, animated: true, completion: nil)
            }
        case .detail:
            DispatchQueue.main.async {
                let nav = UINavigationController(rootViewController: target)
                sender.showDetailViewController(nav, sender: nil)
            }
        case .alert:
            DispatchQueue.main.async {
                sender.present(target, animated: true, completion: nil)
            }
        case .mine :
            DispatchQueue.main.async {
                sender.navigationController?.pushViewController(target, animated: true)
            }
        default : break
        }
    }
}
